/**

This file is part of MaCI/GIMnet.

MaCI/GIMnet is free software: you can redistribute it and/or modify it 
under the terms of the GNU Lesser General Public License as published 
by the Free Software Foundation, either version 3 of the License, or 
(at your option) any later version.

MaCI/GIMnet is distributed in the hope that it will be useful, but WITHOUT 
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public 
License for more details.

You should have received a copy of the GNU Lesser General Public 
License along with GIMnet. (See COPYING.LESSER) If not, see 
<http://www.gnu.org/licenses/>.

**/
/**
 * \file 
 * \brief MottiMission decoder/encoder interface
 * \author Antti Maula <antti.maula@tkk.fi>
 *
 * 
 *
 */
#ifndef _MACI_INTERFACES_TASKCTRL_MOTTIMISSION_HPP_
#define _MACI_INTERFACES_TASKCTRL_MOTTIMISSION_HPP_

#include "MottiMissionTypes.hpp"
#include <libxml/parser.h>

namespace Motti {
  
  /**
   * 
   */
  class CMission
  {
  public:
    CMission();
    ~CMission();

    /** Decode MottiMission XML from string.
     *
     *
     * @param[in] aXMLData      XML data to decode as MottiMission.
     * @param[in] aSave         Whether the result should be stored to this instance,
     *                          or just parsed. If 'true' valid result is stored
     *                          inside class instance, on 'false' the tree is
     *                          only decoded and validated and then forgot.
     * @return                  'true' when the decoding was succesfull, meaning
     *                          that the given XML data was correctly validated
     *                          against MottiMission required data structure.
     *                          'false' on any parse error.
     */
    bool DecodeMottiMissionXML(const std::string &aXMLData, bool aSave = true);


    /**  Decode MottiMission XML from file in filesystem.
     *
     * This function differs from function above only by the datasource. 
     *
     * \overload
     * 
     * @return                  Otherwise as above, but errors can also be
     *                          generated from file IO/access errors.
     */
    bool DecodeMottiMissionXMLFile(const std::string &aXMLDataFile, bool aSave = true);
    
    
    /** Encode given MottiMission tree to XML.
     *
     * This function attempts to encode the given MottiMission
     * container to XML.
     *
     * @param[in] aMission      Mission tree to encode.
     * @param[in] aSave Whether the result should be stored to this
     *                          instance, or just parsed. If 'true'
     *                          valid result is stored inside class
     *                          instance, on 'false' the tree is only
     *                          decoded and validated and then forgot.
     *
     * @return 'true' when encoding was succesfull, meaning that the
     *                          given object tree was correctly
     *                          validated against MottiMission
     *                          required data structure.  'false' on
     *                          any error.
     */
    bool EncodeMottiMission(const SMission &aMission, bool aSave = true);
    
    
    /** Return reference to current decoded mission container tree.
     *
     * This function returns constant reference to current mission
     * container tree.
     *
     * \note Caller should check for tree validity by calling
     * 'IsValidMission()' function in case the data was
     * decoded/encoded from unknown source.
     *
     * @return                  Reference to SMission tree.
     *
     */
    const SMission &GetMission(void) const;


    /** Return reference to current encoded XML representation of mission.
     *
     * This functions returns a XML data from where or where to a
     * mission data was decoded/encoded.
     *
     * \note Caller should check for tree validity by calling
     * 'IsValidMission()' function in case the data was
     * decoded/encoded from unknown source.
     * 
     * @return                  XML string representation of mission tree.
     *
     */
    const std::string &GetMissionXML(void) const;


    /** Does the current object contain a valid mission.
     *
     * If the current object contains a valid mission, the function
     * returns true, otherwise false is returned.
     *
     * @return                  'true' if current mission is valid,
     *                          otherwise 'false'.
     */
    bool IsValidMission(void) const {
      return iIsValidMission;
    }


  private:
    bool DecodeTagMission(SMission &aMission, xmlDocPtr docp, xmlNodePtr nodep);
    bool DecodeTagMissionHeader(SMissionHeader &aHeader, xmlDocPtr docp, xmlNodePtr nodep);
    bool DecodeTagPallets(SPallets &aPallets, xmlDocPtr docp, xmlNodePtr nodep);

    bool DecodeTagPallet(SPallet &aPallet, xmlDocPtr docp, xmlNodePtr nodep);
    bool DecodeTagGetEmpty(SGetEmpty &aGetEmpty, xmlDocPtr docp, xmlNodePtr nodep);
    bool DecodeTagFill(SFill &aFill, xmlDocPtr docp, xmlNodePtr nodep);
    bool DecodeTagTransport(STransport &aTransport, xmlDocPtr docp, xmlNodePtr nodep);
    bool DecodeTagPick(SPick &aPick, xmlDocPtr docp, xmlNodePtr nodep);

    bool ExtractMissionLocation(SMissionLocation &aMissionLocation, xmlDocPtr docp, xmlNodePtr nodep);
    bool ExtractNodeHeader(std::string &aId, std::string &aRule, 
                           std::string &aTrigger, xmlDocPtr docp, xmlNodePtr nodep);
    bool ExtractNodeHeader(SNodeHeader &aNodeHeader,
                           xmlDocPtr docp, xmlNodePtr nodep);

  private:
    std::string iXMLData;
    SMission iMission;
    bool iIsValidMission;

  };

}

#endif
